<?php

namespace beObject\Sql;

use beObject\Object;
use beObject\Primitive\String;

  /**
   * This class provides all methods to interact with MySQL server.<br />
   * Store all parameters in private privateiables.<br />
   * Once the MySQL object is built, the connection is opened, dans the
   * database selected.<br />
   *
   * @param $host The MySQL host name.
   * @param $login The login to connect to MLySQL server.
   * @param $password The password to connect to MySQL server.
   * @param $database The database to work with.
   *
   * @see <a href="http://be.php.net/manual/en/function.mysql-connect.php">mysqlconnect()</a>
   * @see <a href="http://be.php.net/manual/en/function.mysql-select-db.php">mysqlselectdb()</a>
   *
   * @author Dany Mottier
   * @version 2.1.4
   */
  class MySQL extends Object {

    /** @var resource A MySQL link identifier. */
    private $handle = null;

    /** @var string The hostname pf the MySQL server. */
    private $host = "";

    /** @var string The login to connect to the database. */
    private $login = "";

    /** @var string The password to connect to the database. */
    private $password = "";

    /** @var string The database to work with. */
    private $database = "";

    /** @var boolean Property used to define if class is connected to server. */
    private $connected = false;

    /**
     * Store all parameters in private privateiables.<br />
     * Once the MySQL object is built, the connection is opened, dans the
     * database selected.<br />
     *
     * @param $host The MySQL host name.
     * @param $login The login to connect to MLySQL server.
     * @param $password The password to connect to MySQL server.
     * @param $database The database to work with.
     *
     * @link http://be.php.net/manual/en/function.mysql-connect.php
     * @llink http://be.php.net/manual/en/function.mysql-select-db.php
     */
    public function __construct($host = "localhost", $login = "root", $password = "", $database = "") {
      $this->host = new String($host);
      $this->login = new String($login);
      $this->password = new String($password);
      $this->database = new String($database);

      $this->handle = mysql_connect($this->host, $this->login, $this->password);

      if (!empty($this->database)) {
        if (is_resource($this->handle)) {
          $this->connected = mysql_selectdb($this->database, $this->handle);
        }
      }
    }

    /** Disconnect from server. */
    public function __destruct() {
      $this->Disconnect();
    }

    /**
     * Returns TRUE if My SQL handle is not null.
     * @return boolean Returns TRUE if connected.
     */
    public function isConnected() {
      return $this->connected;
    }

    /** Disconnect from My SQL database. */
    public function disconnect() {
      if ($this->isConnected())
        $this->connected = !mysql_close($this->handle);
    }

    /**
     * Execute any query from the My SQL database.<br />
     * The returned resource is the handle of mysqlquery.<br />
     *
     * @return A mixed privateiable as a scalar or an array instead of the query.
     * On error raised or if there is no result, the method returns NULL.<br /><br />
     *
     * @see <a href="http://be.php.net/manual/en/function.mysql-query.php">mysqlquery()</a>
     */
    public function executeQuery($query) {
      if (is_string($query)) {
        if ($this->isConnected()) {
          return mysql_query($query);
        } else {
          return null;
        }
      }
    }

    /**
     * Fetch a result row as an associative array, a numeric array, or both.<br />
     * Returns an array that corresponds to the fetched row and moves the
     * internal data pointer ahead.<br />
     *
     * @param $result The result resource that is being evaluated. This result
     * comes from a call to ExecuteQuery().
     * @param $type This parameter takes constant, these are MYSQLASSOC for
     * only association field, MYSQLNUM for only numbered field and,
     * the default value, MYSQLBOTH for each one.
     *
     * @return An array of strings that corresponds to the fetched row, or FALSE
     * if there are no more rows.<br /><br />
     *
     * @see <a href="http://be.php.net/manual/en/function.mysql-fetch-array.php">mysqlfetcharray()</a>
     */
    public function fetchArray($result, $type = MYSQL_BOTH) {
      return mysql_fetch_array($result, $type);
    }

    /**
     * Returns an associative array of the current row in the result.<br />
     * Returns an associative array that corresponds to the fetched row and
     * moves the internal data pointer ahead. FetchAssoc() is equivalent to
     * calling FetchArray() with MYSQL_ASSOC for the second parameter.<br />
     *
     * @param resource $Result The result resource that is being evaluated. This
     * result comes from a call to ExecuteQuery().
     * @return array Returns an associative array of the current row in
     * the result.<br /><br />
     * @see <a href="http://www.php.net/manual/en/function.mysql-fetch-assoc.php">mssql_fetch_assoc()</a>
     */
    public function fetchAssoc($result) {
      return mysql_fetch_assoc($result);
    }

    /**
     * Get the ID generated from the previous INSERT operation.<br />
     * Retrieves the ID generated for an AUTOINCREMENT column by the previous
     * INSERT query.<br />
     *
     * @return The ID generated for an AUTOINCREMENT column by the previous
     * INSERT query on success, 0 if the previous query does not generate an
     * AUTOINCREMENT value, or FALSE if no MySQL connection was established.<br /><br />
     *
     * @see <a href="http://be.php.net/manual/en/function.mysql-insert-id.php">mysqlinsertid()</a>
     */
    public function getLastInsertedId() {
      return mysql_insert_id($this->handle);
    }

    /**
     * Get number of affected rows in previous MySQL operation.<br />
     * Get the number of affected rows by the last INSERT, UPDATE, REPLACE or
     * DELETE query associated.<br />
     *
     * @return The number of affected rows on success, and -1 if the last query
     * failed.<br /><br />
     *
     * @see <a href="http://be.php.net/manual/en/function.mysql-affected-rows.php">mysqlaffectedrows()</a>
     */
    public function getAffectedRows() {
      return mysql_affected_rows($this->handle);
    }

    /**
     * Change logged in user of the active connection.<br />
     * Changes the logged in user of the current active connection. If a
     * database is specified, this will be the current database after the user
     * has been changed. If the new user and password authorization fails, the
     * current connected user stays active.<br />
     *
     * @param $login The new MySQL username.
     * @param $password The new MySQL password.
     * @param $database The MySQL database. If not specified, the current
     * selected database is used.
     *
     * @return TRUE on success or FALSE on failure.<br /><br />
     *
     * @see <a href="http://be.php.net/manual/en/function.mysql-change-user.php">mysqlchangeuser()</a>
     */
    public function changeUser($login = "root", $password = "", $database = "") {
      if (Validator::Validate(array($login, $password, $database), Validator::STRING)) {
        $this->login = $login;
        $this->password = $password;
        $this->database = $database;

        return mysql_changeuser($this->login, $this->password, $this->database, $this->handle);
      }
    }

    /**
     * Returns the name of the character set.<br />
     * Retrieves the characterset privateiable from MySQL.<br />
     *
     * @return The default character set name for the current connection.<br /><br />
     *
     * @see <a href="http://be.php.net/manual/en/function.mysql-client-encoding.php">mysqlclientencoding()</a>
     */
    public function getClientEncoding() {
      return mysql_clientencoding($this->handle);
    }

    /**
     * Create a MySQL database.<br />
     * Attempts to create a new database on the server.<br />
     *
     * @param $database The name of the database being created.
     * @return TRUE on success or FALSE on failure.<br /><br />
     * @see <a href="http://be.php.net/manual/en/function.mysql-create-db.php">mysqlcreatedb()</a>
     */
    public function createDatabase($database) {
      if (Validator::Validate($database, Validator::STRING))
        return mysql_createdb($database, $this->handle);
    }

    /**
     * @deprecated
     * Drop (delete) a MySQL database.<br />
     * Attempts to drop (remove) an entire database from the server. This
     * function is deprecated, it is preferable to use ExecuteQuery() to issue
     * a sql DROP DATABASE statement instead.<br />
     *
     * @param $database The name of the database that will be deleted.
     * @return TRUE on success or FALSE on failure.<br /><br />
     * @see <a href="http://be.php.net/manual/en/function.mysql-drop-db.php">mysqldropdb()</a>
     */
    public function drop($database) {
      if (Validator::Validate($database, Validator::STRING))
        return mysql_dropdb($database, $this->handle);
    }

    /**
     * Returns the numerical value of the error message from previous
     * MySQL operation.<br />
     * Returns the error number from the last MySQL function.<br />
     * @return The error number from the last MySQL function, or 0 (zero) if no
     * error occurred.<br /><br />
     * @see <a href="http://be.php.net/manual/en/function.mysql-errno.php">mysqlerrno()</a>
     */
    public function getErrorNumber() {
      return mysql_errno($this->handle);
    }

    /**
     * Returns the text of the error message from previous MySQL operation.<br />
     * Returns the error text from the last MySQL function. Errors coming back
     * from the MySQL database backend no longer issue warnings. Instead, use
     * getError() to retrieve the error text. Note that this function only
     * returns the error text from the most recently executed MySQL function
     * (not including getError() and getErrorNumber()), so if you want to use
     * it, make sure you check the value before calling another MySQL function.<br />
     *
     * @return The error text from the last MySQL function, or '' (empty string)
     * if no error occurred.<br /><br />
     *
     * @see <a href="http://be.php.net/manual/en/function.mysql-error.php">mysqlerror()</a>
     */
    public function getError() {
      return mysql_error($this->handle);
    }

    /**
     * Get the flags associated with the specified field in a result.<br />
     * @param resource $result The result resource that is being evaluated. This
     * result comes from a call to ExecuteQuery().
     * @param integer $FieldOffset The numerical field offset. The FieldOffset
     * starts at 0. If FieldOffset does not exist, an error of level E_WARNING
     * is also issued.
     * @return mixed Returns a string of flags associated with the result, or
     * FALSE on failure.<br /><br />
     * @see <a href="http://be2.php.net/manual/en/function.mysql-field-flags.php">mysql_fieldflags()</a>
     */
    public function getFieldFlag($result, $FieldOffset) {
      if (Validator::Validate($result, Validator::RESOURCE) &&
              Validator::Validate($FieldOffset, Validator::INTEGER))
        return mysql_fieldflags($result, $FieldOffset);
    }

    /**
     * Returns the length of the specified field in a result.<br />
     * Returns the field flags of the specified field. The flags are reported as
     * a single word per flag separated by a single space, so that you can split
     * the returned value using String::Explode().<br />
     *
     * @param $result The result resource that is being evaluated. This result
     * comes from a call to ExecuteQuery().
     * @param $offset The numerical field offset. The $offset starts at 0.
     *
     * @exception EWARING If $offset does not exist, an error of level
     * EWARNING is also issued.
     *
     * @return A string of flags associated with the result, or FALSE on
     * failure.<br /><br />
     *
     * @see ExecuteQuery()
     * @see <a href="http://be.php.net/manual/en/function.mysql-field-flags.php">mysqlfieldlen()</a>
     */
    public function getFieldLength($result, $offset) {
      if (Validator::Validate($result, Validator::RESOURCE) &&
              Validator::Validate($offset, Validator::INTEGER))
        return mysql_fieldlen($result, $offset);
    }

    /**
     * Get the name of the specified field in a result.<br />
     * Returns the name of the specified field index.<br />
     *
     * @param $result The result resource that is being evaluated.
     * @param $offset The numerical field offset. The $offset starts at 0.
     *
     * @exception EWARING If $offset does not exist, an error of level
     * EWARNING is also issued.
     *
     * @return The name of the specified field index on success, or FALSE on
     * failure.<br /><br />
     *
     * @see <a href="http://be.php.net/manual/en/function.mysql-field-name.php">mysqlfieldname()</a>
     */
    public function getFieldName($result, $offset) {
      if (Validator::Validate($result, Validator::RESOURCE) &&
              Validator::Validate($offset, Validator::INTEGER))
        return mysql_fieldname($result, $offset);
    }

    /**
     * Get name of the table the specified field is in.<br />
     * Returns the name of the table that the specified field is in.<br />
     *
     * @param $result The result resource that is being evaluated.
     * @param $offset The numerical field offset. The $offset starts at 0.
     *
     * @exception EWARING If $offset does not exist, an error of level
     * EWARNING is also issued.
     *
     * @return The name of the table on success.<br /><br />
     *
     * @see <a href="http://be.php.net/manual/en/function.mysql-field-table.php">mysqlfieldtable()</a>
     */
    public function getFieldTable($result, $offset) {
      if (Validator::Validate($result, Validator::RESOURCE) &&
              Validator::Validate($offset, Validator::INTEGER))
        return mysql_fieldtable($result, $offset);
    }

    /**
     * Get the type of the specified field in a result.<br />
     * is similar to thegetFieldName() function. The arguments are identical,
     * but the field type is returned instead.<br />
     *
     * @param $result The result resource that is being evaluated.
     * @param $offset The numerical field offset. The $offset starts at 0.
     *
     * @exception EWARING If $offset does not exist, an error of level
     * EWARNING is also issued.
     *
     * @return The returned field type will be one of "int", "real", "string",
     * "blob", and others as detailed in the MySQL documentation.<br /><br />
     *
     * @see <a href="http://dev.mysql.com/doc/">MySQL documentation</a>
     * @see <a href="http://be.php.net/manual/en/function.mysql-field-type.php">mysqlfieldtype()</a>
     */
    public function getFieldType($result, $offset) {
      if (Validator::Validate($result, Validator::RESOURCE) &&
              Validator::Validate($offset, Validator::INTEGER))
        return mysql_fieldtype($result, $offset);
    }

    /**
     * Get MySQL client info.<br />
     * Returns a string that represents the client library version.<br />
     *
     * @return The MySQL client version.<br /><br />
     * @see <a href="http://be.php.net/manual/en/function.mysql-get-client-info.php">mysqlgetclientinfo()</a>
     */
    public function getClientInfo() {
      return mysql_getclientinfo();
    }

    /**
     * Get MySQL host info.<br />
     * Describes the type of connection in use for the connection, including the
     * server host name.<br />
     *
     * @return Astring describing the type of MySQL connection in use for the
     * connection or FALSE on failure.<br /><br />
     *
     * @see <a href="http://be.php.net/manual/en/function.mysql-get-host-info.php">mysqlgethostinfo</a>
     */
    public function getHostInfo() {
      return mysql_gethostinfo($this->handle);
    }

    /**
     * Return the current thread ID.<br />
     * Retrieves the current thread ID. If the connection is lost, and a
     * reconnect with Ping() is executed, the thread ID will change. This means
     * only retrieve the thread ID when needed.<br />
     *
     * @return The thread ID on success, or FALSE on failure.<br /><br />
     *
     * @see <a href="http://be.php.net/manual/en/function.mysql-thread-id.php">mysqlthreadid()</a>
     */
    public function getThreadId() {
      return mysql_threadid($this->handle);
    }

    /**
     * Get result data.<br />
     * Retrieve the database name from a call to ListDatabases().<br />
     *
     * @param $result The result pointer from a call to ListDatabases().
     * @param $Row The index into the result set.
     * @param $Field The field name.
     *
     * @return he database name on success, and FALSE on failure. If FALSE is
     * returned, use getError() to determine the nature of the error.<br /><br />
     *
     * @see <a href="http://be.php.net/manual/en/function.mysql-db-name.php">mysqldbname</a>
     */
    public function getDatabaseName($result, $Row, $Field = NULL) {
      if (Validator::Validate($result, Validator::RESOURCE) &&
              Validator::Validate($Row, Validator::INTEGER)) {
        if (!empty($Field))
          if (Validator::Validate($Field, Validator::STRING))
            return mysql_dbname($result, $Row, $Field);
          else
            return mysql_dbname($result, $Row);
      }
    }

    /**
     * Get MySQL server info.<br />
     * Retrieves the MySQL server version.<br />
     *
     * @return The MySQL server version on success, or FALSE on failure.<br /><br />
     * @see <a href="http://be.php.net/manual/en/function.mysql-get-server-info.php">mysqlgetserverinfo()</a>
     */
    public function getServerInfo() {
      return mysql_getserverinfo($this->handle);
    }

    /**
     * Get information about the most recent query.<br />
     * Returns detailed information about the last query.<br />
     *
     * @return Returns information about the statement on success, or FALSE on
     * failure. See the example below for which statements provide information,
     * and what the returned value may look like. Statements that are not listed
     * will return FALSE.<br /><br />
     *
     * @see <a href="http://be.php.net/manual/en/function.mysql-info.php">mysqlinfo()</a>
     */
    public function getInformations() {
      return mysql_info($this->handle);
    }

    /**
     * List databases available on a MySQL server.<br />
     * Returns a result pointer containing the databases available from the
     * current mysql daemon.<br />
     *
     * @return Returns a result pointer resource on success, or FALSE on
     * failure. Use the getTableName() function to traverse this result pointer,
     * or any function for result tables, such as FetchArray().<br /><br />
     *
     * @see <a href="http://be.php.net/manual/en/function.mysql-list-dbs.php">mysqllistdbs()</a>
     */
    public function listDatabases() {
      return mysql_listdbs($this->handle);
    }

    /**
     * List MySQL table fields.<br />
     * Retrieves information about the given table name.<br />
     *
     * @param $database The name of the database that's being queried.
     * @param $Table The name of the table that's being queried.
     *
     * @return  A result pointer resource on success, or FALSE on failure. The
     * returned result can be used with getFieldFlag(), getFieldLength(),
     * getFieldName() and getFieldType().<br /><br />
     *
     * @see <a href="http://be.php.net/manual/en/function.mysql-list-fields.php">mysqllistfields()</a>
     */
    public function listFields($database, $Table) {
      if (Validator::Validate(array($database, $Table), Validator::STRING))
        return mysql_listfields($database, $Table, $this->handle);
    }

    /**
     * List MySQL processes.<br />
     * Retrieves the current MySQL server threads.<br />
     *
     * @return A result pointer resource on success, or FALSE on failure.<br /><br />
     * @see <a href="http://be.php.net/manual/en/function.mysql-list-processes.php">mysqllistprocesses()</a>
     */
    public function listProcess() {
      return mysql_listprocesses($this->handle);
    }

    /**
     * List tables in a MySQL database.<br />
     * Retrieves a list of table names from a MySQL database.<br />
     *
     * @param $database The name of the database
     * @return  A result pointer resource on success, or FALSE on failure. Use
     * the getTableName() function to traverse this result pointer, or any
     * function for result tables, such as FetchArray().<br /><br />

     * @see <a href="http://be.php.net/manual/en/function.mysql-list-tables.php">mysqllisttables</a>
     */
    public function listTables($database) {
      if (Validator::Validate($database, Validator::STRING))
        return mysql_listtables($database);
    }

    /**
     * Get number of fields in result.<br />
     * Retrieves the number of fields from a query.<br />
     *
     * @param $result The result resource that is being evaluated. This result
     * comes from a call to ExecuteQuery().
     *
     * @return The number of fields in the result set resource on success, or
     * FALSE on failure.<br /><br />
     *
     * @see <a href="http://be.php.net/manual/en/function.mysql-num-fields.php">mysqlnumfields()</a>
     */
    public function countFields($result) {
      return mysql_numfields($result);
    }

    /**
     * Get number of rows in result.<br />
     * Retrieves the number of rows from a result set. This command is only
     * valid for statements like SELECT or SHOW that return an actual result
     * set. To retrieve the number of rows affected by a INSERT, UPDATE, REPLACE
     * or DELETE query, use getAffectedRows().<br />
     *
     * @param $result The result resource that is being evaluated. This result
     * comes from a call to ExecuteQuery().
     *
     * @return The number of rows in a result set on success, or FALSE on failure.<br /><br />
     *
     * @see <a href="http://be.php.net/manual/en/function.mysql-num-rows.php">mysqlnumrows()</a>
     */
    public function countRows($result) {
      return mysql_numrows($result);
    }

    /**
     * Ping a server connection or reconnect if there is no connection.<br />
     * Checks whether or not the connection to the server is working. If it has
     * gone down, an automatic reconnection is attempted. This function can be
     * used by scripts that remain idle for a long while, to check whether or
     * not the server has closed the connection and reconnect if necessary.<br />
     *
     * @return TRUE if the connection to the server MySQL server is working,
     * otherwise FALSE.<br /><br />
     *
     * @see <a href="http://be.php.net/manual/en/function.mysql-ping.php">mysqlping()</a>
     */
    public function ping() {
      return mysql_ping($this->handle);
    }

    /**
     * Escapes special characters in a string for use in a SQL statement.<br />
     * Escapes special characters in the unescapedstring , taking into account
     * the current character set of the connection so that it is safe to place
     * it in a mysqlquery(). If binary data is to be inserted, this function
     * must be used. This function could be called as an abstract one.<br />
     *
     * @param $string The string that is to be escaped.
     *
     * @return The escaped string, or FALSE on error.<br /><br />
     *
     * @see <a href="http://be.php.net/manual/en/function.mysql-real-escape-string.php">mysqlrealescapestring()</a>
     */
    public function realEscapeString($string) {
      return mysql_real_escape_string($string, $this->handle);
    }

    /**
     * Set the database name in private privateiable for further use.<br />
     * @param $database The name of the database.
     */
    public function setDataBase($database) {
      if (Validator::Validate($database, Validator::STRING))
        $this->database = $database;
    }

    /**
     * Sets the client character set.<br />
     * Sets the default character set for the current connection.<br />
     *
     * @param $charset A valid character set name.
     *
     * @return TRUE on success or FALSE on failure.<br /><br />
     *
     * @see <a href="http://be.php.net/manual/en/function.mysql-set-charset.php">mysqlsetcharset()</a>
     */
    public function setCharset($charset) {
      if (Validator::Validate($charset, Validator::STRING))
        return mysql_setcharset($charset, $this->handle);
    }

    /**
     * Get current system status.<br />
     * Returns the current server status.<br />
     *
     * @return A string with the status for uptime, threads, queries, open
     * tables, flush tables and queries per second. For a complete list of other
     * status privateiables, you have to use the SHOW STATUS SQL command.<br /><br />
     *
     * @see <a href="http://be.php.net/manual/en/function.mysql-stat.php">mysqlstat()</a>
     */
    public function getStatus() {
      return mysql_stat($this->handle);
    }

    /**
     * Get table name of field.<br />
     * Retrieves the table name from a result.<br />
     *
     * @param $result A result pointer resource that's returned from
     * ListTables().
     *
     * @param $offset The integer index (row/table number)
     *
     * @return The name of the table on success, or FALSE on failure. Use the
     * getTableName() function to traverse this result pointer, or any function
     * for result tables, such as FetchArray().<br /><br />
     *
     * @see <a href="http://be.php.net/manual/en/function.mysql-tablename.php">mysqltablename()</a>
     */
    public function getTableName($result, $offset) {
      if (Validator::Validate($result, Validator::RESOURCE) &&
              Validator::Validate($offset, Validator::INTEGER))
        return mysql_tablename($result, $offset);
    }

  }

?>
